package com.kkshop.gwt.widget.wizard.impl;

import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.SourcesChangeEvents;
import com.google.gwt.user.client.ui.SourcesKeyboardEvents;
import com.google.gwt.user.client.ui.Widget;

import com.kkshop.gwt.widget.wizard.Wizard;
import com.kkshop.gwt.widget.wizard.WizardPage;

public abstract class AbstractWizardPage implements WizardPage {

    protected ChangeListener defaultChangeListener;
    private KeyboardListener defaultKeyboardListener;

    private Wizard wizard;
    protected String errorMessage = null;
    protected String name;

    public AbstractWizardPage(String name) {
        this.name = name;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public String getName() {
        return name;
    }

    /**
     * Subclasses may call this method to set an error message.
     * 
     * @param errorMessage
     *            the new error message
     * @return true if errorMessage == null, false otherwise (ie. you can simply
     *         use it in isFinished() in an return statement)
     * @see #getErrorMessage()
     */
    protected boolean setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
        return errorMessage == null;
    }

    /**
     * the default implementation simply returns {@link WizardPage#isFinished()}
     */
    public boolean canFlipToNextPage() {
        return isFinished();
    }

    /**
     * adds a change listener to the given widget which will call #isFinished()
     * each time something changes.
     * 
     * @param widget
     */
    protected void addChangeListener(SourcesChangeEvents widget) {
        if (defaultChangeListener == null)
            defaultChangeListener = new ChangeListener() {
                public void onChange(Widget sender) {
                    doUpdateButtons();
                }
            };
        widget.addChangeListener(defaultChangeListener);
    }

    /**
     * adds a keyboard listener which will call updateButtons onKeyUp. (This is
     * needed for TextBox'es)
     * 
     * @param widget
     */
    protected void addKeyboardListener(SourcesKeyboardEvents widget) {
        if (defaultKeyboardListener == null)
            defaultKeyboardListener = new KeyboardListener() {
                public void onKeyUp(Widget sender, char keyCode, int modifiers) {
                    doUpdateButtons();
                }

                public void onKeyPress(Widget sender, char keyCode, int modifiers) {
                }

                public void onKeyDown(Widget sender, char keyCode, int modifiers) {
                }
            };
        widget.addKeyboardListener(defaultKeyboardListener);
    }

    /**
     * Depending on the type of widget this method will add all available
     * listeners (like onChange listener, keyboard listener, etc.)
     * 
     * @param widget
     */
    protected void addAllAvailableListeners(Widget widget) {
        if (widget instanceof SourcesKeyboardEvents)
            addKeyboardListener((SourcesKeyboardEvents) widget);
        if (widget instanceof SourcesChangeEvents)
            addChangeListener((SourcesChangeEvents) widget);
    }

    public void doUpdateButtons() {
        getWizard().getWizardWidget().updateButtons();
        getWizard().getWizardWidget().updateMessage();
    }

    public void setWizard(Wizard wizard) {
        this.wizard = wizard;
    }

    public Wizard getWizard() {
        return this.wizard;
    }
}
